package com.powerunion.datacollection.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import net.sf.json.JSONArray;

import org.apache.log4j.Logger;
import com.powerunion.datacollection.common.Constants;
import com.powerunion.datacollection.common.Format;
import com.powerunion.datacollection.common.SystemException;
import com.powerunion.datacollection.config.ConfigUtil;
import com.powerunion.datacollection.dao.CollectionTaskInstanceDao;
import com.powerunion.datacollection.dao.DaoException;
import com.powerunion.datacollection.model.CollectionTaskInstance;
import com.powerunion.datacollection.model.jsonObject.CollectionTaskInstanceJO;
import com.powerunion.datacollection.persistence.db.jdbc.operator.QueryOperator;
import com.powerunion.datacollection.persistence.db.jdbc.operator.RsDataSet;
import com.powerunion.datacollection.persistence.db.jdbc.operator.SqlParameter;
import com.powerunion.datacollection.persistence.db.jdbc.operator.SqlParameterSet;
import com.powerunion.datacollection.persistence.db.jdbc.operator.SqlType;
import com.powerunion.datacollection.persistence.db.jdbc.operator.UpdateOperator;
import com.powerunion.datacollection.workflow.domain.TaskInstance;
import com.powerunion.util.DBUtils;
import com.powerunion.util.log.LogHelper;

public class CollectionTaskInstanceDaoImpl extends JdbcBase implements
		CollectionTaskInstanceDao {
	// 初始化日志类
	private static final Logger logger = LogHelper.getInstance().getLogger(
			CollectionTaskInstanceDaoImpl.class);

	public boolean delete(String[] codes) throws DaoException{
		if (logger.isDebugEnabled()) {
			logger.debug(Constants.INTOMETHOD + "delete");
		}
		String sql = "delete from dc_wf_instance where id = ? and state = 0";
		UpdateOperator update = new UpdateOperator();
		update.setSql(sql);

		for (int i = 0; i < codes.length; i++) {
			SqlParameterSet spSet = new SqlParameterSet();
			spSet.addParameter(new SqlParameter(SqlType.VARCHAR, codes[i]));
			update.addBatchParameter(spSet);
		}
		try{
			update.access();
		}catch(Exception e){
			logger.error("", e);
			throw new DaoException("删除任务实例出错!");
		}
		
		int[] effectCount = update.getBatchEffectCounts();
		if (effectCount != null && effectCount.length > 0) {
			if (logger.isDebugEnabled()) {
				logger.debug("delete:" + Constants.DELETE + "采集任务实例信息"
						+ Constants.SUCCESS);
			}
			return true;
		} else {
			if (logger.isDebugEnabled()) {
				logger.debug("delete:" + Constants.DELETE + "采集任务实例信息"
						+ Constants.FAIL);
			}
			return false;
		}

	}
 
	public TaskInstance save(TaskInstance ct) throws DaoException{
		if (logger.isDebugEnabled()) {
			logger.debug(Constants.INTOMETHOD + "save");
		}
		String sql = "";
		String id = String.valueOf(this.getSeq("dc_wf_instance"));
		ct.setId(id);
		StringBuffer sqlSave = new StringBuffer();
		sqlSave
				.append(
						"insert into dc_wf_instance (wf_id,wf_name,wf_instance_desc,date_created,crt_user,")
				.append(
						"state,form_id,proc_id,id,wf_type,submit_type,periods_time,exactly_time) ")
				.append(" values(?,?,?,?,?,?,?,?,?,?,?,?,?)");
		sql = sqlSave.toString();

		UpdateOperator update = new UpdateOperator();
		update.setSql(sql);
		update.addParameter(new SqlParameter(SqlType.VARCHAR, ct
				.getTaskDefineId()));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, ct.getName()));
logger.debug("保存id为："+id+" 任务名："+ ct.getName()+"任务");
		update.addParameter(new SqlParameter(SqlType.VARCHAR, ct
				.getDescription()));
		update.addParameter(new SqlParameter(SqlType.DATE, new java.sql.Date(ct
				.getCreateDate().getTime())));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, ct
				.getCrtUserCode()));
//		update.addParameter(new SqlParameter(SqlType.INTEGER, new Integer(ct
//				.getState())));
		update.addParameter(new SqlParameter(SqlType.INTEGER, new Integer(1)));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, ct.getFormId()));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, ct.getProcId()));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, ct.getId()));
		update.addParameter(new SqlParameter(SqlType.INTEGER, new Integer(ct
				.getType())));
		update.addParameter(new SqlParameter(SqlType.INTEGER, new Integer(ct
				.getSubmitType())));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, ct.getPeriodsTime()));
		update.addParameter(new SqlParameter(SqlType.VARCHAR, ct.getExactlyTime()));
		
		try {
			update.access();
		} catch (Exception e) {
			logger.error("保存任务实例失败,任务实例id:" + ct.getId() + " 任务实例名："
					+ ct.getName(), e);
			throw new DaoException("保存任务实例失败,任务实例id:" + ct.getId() + " 任务实例名："
					+ ct.getName());
		}

		int effectCount = update.getEffectCounts();
		if (effectCount > 0) {
			return ct;
		} else {
			return null;
		}
	}

	public CollectionTaskInstance getBykey(String id) throws DaoException{
		CollectionTaskInstance ct = new CollectionTaskInstance();
		StringBuffer sql = new StringBuffer();
		sql
				.append(
						"select d.wf_id, d.wf_name,d.wf_instance_desc,d.date_created,d.crt_user,d.state,")
				.append(
						"d.form_id,d.proc_id,d.id,f.user_name,d.wf_type,d.submit_type,d.periods_time,d.exactly_time ")
				.append(
						"from dc_wf_instance d left join frameuser f on d.crt_user = f.user_code where d.id = ?");
		QueryOperator query = new QueryOperator();
		query.setSql(sql.toString());
		query.addParameter(new SqlParameter(SqlType.VARCHAR, id));
		try{
			query.access();
		}catch(Exception e){
			logger.error("", e);
			throw new DaoException("查找ID为："+id+" 的任务实例出错！");
		}
		
		if (query.resultSetAvailable()) {// 检查结果集是否可用
			// 获取并处理记录集
			RsDataSet rs = new RsDataSet(query.getSqlResultSet());
			if (rs.rowCount > 0) {
				ct.setId(rs.getFieldValueAsString("id"));
				ct.setTaskDefineId(rs.getFieldValueAsString("wf_id"));
				ct.setName(rs.getFieldValueAsString("wf_name"));
				ct.setDescription(rs.getFieldValueAsString("wf_instance_desc"));
				ct.setCreateDate(rs.getFieldValueAsDate("date_created"));
				ct.setCrtUserCode(rs.getFieldValueAsString("crt_user"));
				ct.setState(rs.getFieldValueAsInteger("state").intValue());
				ct.setFormId(rs.getFieldValueAsString("form_id"));
				ct.setProcId(rs.getFieldValueAsString("proc_id"));
				ct.setCrtUserName(rs.getFieldValueAsString("user_name"));
				ct.setType(rs.getFieldValueAsInteger("wf_type").intValue());
				ct.setSubmitType(rs.getFieldValueAsInteger("submit_type").intValue());
				ct.setPeriodsTime(rs.getFieldValueAsString("periods_time"));
				ct.setExactlyTime(rs.getFieldValueAsString("exactly_time"));
			}
			rs.clearAll();
		}
		return ct;
	}

	public String getCollectionTaskInstances(int start,int limit,String userCode) {
		logger.debug(Constants.INTOMETHOD + "getCollectionTaskInstances");
		StringBuffer sqlStr = new StringBuffer();
		String managerUserCode = ConfigUtil.getInstance().getParameter("system.manager.name");
		if(userCode.equals(managerUserCode)){
			sqlStr
			.append(
					"select d.wf_id, d.wf_name,d.wf_instance_desc,d.date_created,d.crt_user,d.state,")
			.append(
					"d.form_id,d.proc_id,d.id,f.user_name,t.item_name,d.wf_type,c.item_name form_name ")
			.append(
					",d.submit_type,d.periods_time,d.exactly_time from dc_wf_instance d left join frameuser f on d.crt_user = f.user_code ")
			.append(
					" left join dc_item_info t on d.proc_id = t.id left join dc_item_info c on d.form_id = c.id order by d.date_created desc");
		}else{
			sqlStr
			.append(
					"select d.wf_id, d.wf_name,d.wf_instance_desc,d.date_created,d.crt_user,d.state,")
			.append(
					"d.form_id,d.proc_id,d.id,f.user_name,t.item_name,d.wf_type,c.item_name form_name ")
			.append(
					",d.submit_type,d.periods_time,d.exactly_time from dc_wf_instance d left join frameuser f on d.crt_user = f.user_code ")
			.append(
					" left join dc_item_info t on d.proc_id = t.id left join dc_item_info c on d.form_id = c.id ")
			.append(" where d.crt_user = ? order by d.date_created desc");
		}

		String sql = sqlStr.toString();

		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = this.getConnection();
			ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
			ps.setMaxRows(start+limit);
			if(!userCode.equals(managerUserCode)){
				ps.setString(1, userCode);
			}
			rs = ps.executeQuery();
			//将游标移动到要输出的第一条记录
			rs.first();
			rs.relative(start-1);
			
			List pageList = new ArrayList();
			while(rs.next()) {
				CollectionTaskInstanceJO ctjo = this.getCTJO(rs);
				pageList.add(ctjo);
			}

			// 转化成JSON数组
			JSONArray jsonarr = JSONArray.fromObject(pageList);
			StringBuffer resultStr = new StringBuffer();
			int total = this.totalRecord(conn, userCode);
			resultStr.append("{total:").append(total).append(",results:")
					.append(jsonarr).append("}");
			logger.debug("getTargets:" + Constants.SEARCH + "targets"
					+ Constants.SUCCESS);
			return resultStr.toString();
			
		} catch (Exception e) {
			logger.error("getTargets:" + Constants.SEARCH
					+ "Targets" + Constants.FAIL,e);
			throw new SystemException("search db record error!");
		}finally{
			DBUtils.close(rs, ps, conn);
		}
	
	}
	
	private int totalRecord(Connection conn,String userCode){
		int count=0;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try{
			String managerUserCode = ConfigUtil.getInstance().getParameter("system.manager.name");
			String sql = "";
			if(userCode.equals(managerUserCode)){
				sql = "select count(id) from dc_wf_instance";
				ps = conn.prepareStatement(sql);
			}else{
				sql = "select count(id) from dc_wf_instance where crt_user = ? ";
				ps = conn.prepareStatement(sql);
				ps.setString(1, userCode);
			}
			
			rs = ps.executeQuery();
			while(rs.next()){
				count = rs.getInt(1);
			}
			
		}catch(Exception e){
			logger.error("totalRecord:" + Constants.SEARCH
					+ "taskIntance totalRecord" + Constants.FAIL);
			logger.error("totalRecord() of throws : ", e);
		}finally{
			DBUtils.close(rs, ps);
		}
		return count;
	}

	public final CollectionTaskInstanceJO getCTJO(ResultSet rs)
			throws SQLException {
		CollectionTaskInstanceJO ctjo = new CollectionTaskInstanceJO();
		ctjo.setId(rs.getString("id"));
		ctjo.setTaskDefineId(rs.getString("wf_id"));
		ctjo.setName(rs.getString("wf_name"));
		ctjo.setDescription(rs.getString("wf_instance_desc"));
		String crtDateStr = Format.getInstance().dateToYMD(
				rs.getDate("date_created"));
		ctjo.setCreateDateStr(crtDateStr);
		ctjo.setCrtUserCode(rs.getString("crt_user"));
		ctjo.setState(rs.getInt("state"));
		ctjo.setFormId(rs.getString("form_id"));
		ctjo.setProcId(rs.getString("proc_id"));
		ctjo.setCrtUserName(rs.getString("user_name"));
		ctjo.setProcName(rs.getString("item_name"));
		ctjo.setFormName(rs.getString("form_name"));
		ctjo.setType(rs.getInt("wf_type"));
		ctjo.setProcFlag(1);
		ctjo.setSubmitType(rs.getInt("submit_type"));
		ctjo.setPeriodsTime(rs.getString("periods_time"));
		ctjo.setExactlyTime(rs.getString("exactly_time"));

		return ctjo;
	}
	
	/**
	 * 修改任务实例状态
	 * @return
	 * @throws DaoException
	 */
	public boolean updateTaskInstanceState(String id,int state) throws DaoException {
		String sql = "update dc_wf_instance set state = ? where id=? and state <> 3 ";
		UpdateOperator update = new UpdateOperator();
		update.setSql(sql);
		update.addParameter(new SqlParameter(SqlType.INTEGER,new Integer(state)));
		update.addParameter(new SqlParameter(SqlType.VARCHAR,id));
		try{
			update.access();
		}catch(Exception e){
			logger.error("更新任务实例状态出错！", e);
			throw new DaoException("更新任务实例状态出错！");
		}

		int effectCount = update.getEffectCounts();
		if(effectCount > 0) {
			
			if (logger.isDebugEnabled()) {
				logger.debug("save:" + Constants.UPDATE + "任务实例状态"
						+ Constants.SUCCESS);
			}
			return true;
		}else{
			if (logger.isDebugEnabled()) {
				logger.debug("save:" + Constants.UPDATE + "任务实例状态"
						+ Constants.FAIL);
			}
			return false;
		}
	}
	
	public boolean updateTaskInstanceStateByProc(String procId,int state) throws DaoException{
		logger.debug(Constants.INTOMETHOD + "updateTaskInstanceStateByProc");
		String sql = "update dc_wf_instance set state = ? where proc_id = ? and state<>3";
		UpdateOperator update = new UpdateOperator();
		update.setSql(sql);
		update.addParameter(new SqlParameter(SqlType.INTEGER,new Integer(state)));
		update.addParameter(new SqlParameter(SqlType.VARCHAR,procId));
		try{
			update.access();
		}catch(Exception e){
			logger.error("更新流程实例ID为："+procId+" 的任务实例状态出错！", e);
			throw new DaoException("更新流程实例ID为："+procId+" 的任务实例状态出错！");
		}

		int effectCount = update.getEffectCounts();
		if(effectCount > 0) {
			
			if (logger.isDebugEnabled()) {
				logger.debug("updateTaskInstanceStateByProc:" + Constants.UPDATE + "流程实例ID为："+procId+" 的任务实例"
						+ Constants.SUCCESS);
			}
			return true;
		}else{
			if (logger.isDebugEnabled()) {
				logger.debug("updateTaskInstanceStateByProc:" + Constants.UPDATE + "流程实例ID为："+procId+" 的任务实例"
						+ Constants.FAIL);
			}
			return false;
		}
	}
	
	
	

}
